package estudoregistry.model;

import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;

public class HiveElement {
        public final static int UNKNOWN = 0;
        public final static int STRING = 1;
        public final static int UNSIGNED_INTEGER = 2;
        public final static int OFFSET = 3;
        public final static int GUID = 4;
        public final static int SIGNED_INTEGER = 5;
        public final static int SECURITY_DESCRIPTOR = 6;
        public final static int FLAG = 7;
        public final static int STRUCTURE_LIST = 8;
        public final static int REGTYPE_ENUMERATION = 9;
        public final static int RAW_DATA = 10;
        public final static int TIMESTAMP64 = 11;


        private final static char[] hexArray = "0123456789ABCDEF".toCharArray();

        private String name;
        private final byte[] data;
        private int dataType;

        public HiveElement(FileInputStream fis, String name, int lenght, int dataType) throws IOException {
            this.name = name;
            this.data = new byte[lenght];
            fis.read(data);
            this.dataType = dataType;
        }

        public HiveElement(byte[] data) {
            this.data = data;
        }

        public byte[] getData() {
            return this.data;
        }

        public String getDataString(int pdataType) {
            switch (pdataType) {
                case UNKNOWN: return bytesToStringFiltered(this.getData());
                case STRING : return bytesToStringFiltered(this.getData());
                case UNSIGNED_INTEGER: return String.valueOf(unsignedIntFromByteArray(this.getData()));
                case OFFSET: return bytesToHex(this.getData());
                case GUID: return bytesToHex(this.getData());
                case SIGNED_INTEGER: return String.valueOf(byteArrayToInt(this.getData()));
                case RAW_DATA: return bytesToStringFiltered(this.getData());
                case TIMESTAMP64: return String.valueOf(unsignedIntFromByteArray(this.getData()));
            }
            return null;
        }

    private static int byteArrayToInt(byte[] b) {
        return new BigInteger(b).intValue();
    }

    private static int unsignedIntFromByteArray(byte[] b) {
        int res = 0;
        if (b == null) {
            return res;
        }

        for (int i = 0; i < b.length; i++) {
            res = (res * 10) + ((b[i] & 0xff));
        }
        return res;
    }

    private static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    private static String bytesToStringFiltered(byte[] b) {
        char[] c = new char[tamanhoFiltrado(b)];
        int j=0;
        for (int i = 0; i < b.length; i++) {
            if (b[i]!=0) {
                c[j] = (char) b[i];
                j++;
            }
        }
        return String.valueOf(c);
    }

    private static int tamanhoFiltrado(byte[] b) {
        int resposta = b.length;
        int tamanhoInicial = resposta;

        for (int i=0;i<tamanhoInicial;i++) {
            
            if (b[i]==0x0) {
                resposta--;
            }
        }
        return resposta;
    }
}
